package top.wshape1.shiziapi.uaa.service.impl;

import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import top.wshape1.shiziapi.common.constant.AuthConstant;
import top.wshape1.shiziapi.common.constant.BizCodeEnum;
import top.wshape1.shiziapi.common.constant.RedisConstant;
import top.wshape1.shiziapi.common.domain.CommonUser;
import top.wshape1.shiziapi.common.domain.to.UserTokenTo;
import top.wshape1.shiziapi.common.exception.CustomException;
import top.wshape1.shiziapi.common.utils.JwtUtil;
import top.wshape1.shiziapi.common.utils.R;
import top.wshape1.shiziapi.uaa.config.ShiZiApiConfig;
import top.wshape1.shiziapi.uaa.domain.User;
import top.wshape1.shiziapi.uaa.mapper.UserMapper;
import top.wshape1.shiziapi.uaa.service.JwtService;

import java.util.concurrent.TimeUnit;

/**
 * @author Wshape1
 * @version 1.0
 * @description
 * @since 2023-08-24
 */

@Service
public class JwtServiceImpl implements JwtService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private ShiZiApiConfig shiZiApiConfig;

    @Override
    public UserTokenTo renewJwt(Long id, String oldToken) {
        String idStr = id.toString();
        String key = RedisConstant.USER_JWT_KEY + idStr;
        if (!oldToken.equals(redisTemplate.opsForValue().get(key))) {
            throw new CustomException(R.instance(BizCodeEnum.ILLEGAL_TOKEN.code(), BizCodeEnum.ILLEGAL_TOKEN.msg()));
        }

        User user = userMapper.selectById(idStr);
        user.setPassword(null);
        String newToken = JwtUtil.createJWT(idStr, JSON.toJSONString(user), shiZiApiConfig.SIGN_KEY);

        Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
        assert expire != null;
        redisTemplate.opsForValue().set(key, newToken, expire, TimeUnit.SECONDS);

        CommonUser commonUser = new CommonUser();
        BeanUtils.copyProperties(user, commonUser);

        return new UserTokenTo(commonUser, newToken);
    }

    @Override
    public void setNewToken(Long id, String oldToken, HttpServletResponse response) {
        UserTokenTo userTokenTo = renewJwt(id, oldToken);
        response.setHeader(AuthConstant.HEADER_NEW_TOKEN_NAME, userTokenTo.getNewToken());
    }
}
